fix(mobile): 44dp touch targets, accessibility, and tokenized model-picker#4385
Merged
Conversation
- Add size='touch' (44dp) to the Button primitive for entry points that need a comfortable tap target. - Add an IconButton typed wrapper that requires accessibilityLabel at the type level so icon-only buttons always have a screen-reader name.
- profile-avatar-button: wrap the 22dp icon in a 44dp container with pressed feedback and hitSlop. - screen-header title dropdown: bump hitSlop so the effective target reaches 44dp; add accessibilityRole and accessibilityLabel derived from the title. - session-list-screen plus/filter: bump hitSlop to 44dp, add accessibilityRole and pressed feedback.
Add hitSlop so the 32dp send/stop Pressables reach a 44dp effective
target. Add accessibilityRole, accessibilityLabel ('Send message' /
'Stop generating'), and accessibilityState to match the back-button
pattern in ScreenHeader.
Replace arbitrary text-[10.5px] / text-[11.5px] / text-[14.5px] in SessionRow and ConfigureRow with the nearest sanctioned size utilities (text-xs / text-sm) so row titles and subtitles read at the floor of comfortable legibility.
- KiloClaw model-picker: replace hardcoded blue selected state (border-blue-500, bg-blue-500/5, #3b82f6) with the brand primary token (border-primary, bg-accent-soft, colors.primary) so the selected indicator matches the rest of the product. Tokenize the decorative 'Balanced' / 'Frontier' icon tints to the existing agent-sky / agent-yuki tile-bg tokens. Enlarge the 'or select from 500+ models' link to a 44dp target with accessibilityRole='link' and a label. - KiloClaw settings model-list: selected check color → colors.primary. - agents child-session-section: replace '#3b82f6' / text-blue-500 with agent-sky tokens so the running-tool indicator matches the brand palette and uses theme-aware dark variants.
Raise the tab-bar label fontSize from 10px to 11px (with a small letter-spacing) so functional navigation identifiers read at the floor of legibility. Keeps JetBrains Mono to match the eyebrow pattern used elsewhere in the app.
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryReviewed all 11 changed files (touch-target/accessibility additions, tokenized colors, and text-size normalization) and found no security, runtime, or logic issues in the changed lines. Files Reviewed (11 files)
Reviewed by claude-sonnet-5-20260630 · Input: 42 · Output: 17.5K · Cached: 1.2M Review guidance: REVIEW.md from base branch |
… drop unused IconButton - model-picker: selected card used opaque bg-accent-soft (#E8F27A in both themes), leaving near-white text and a primary-colored checkmark invisible in dark mode; switch to the established border-primary bg-neutral-100 dark:bg-neutral-800 selected pattern (exec-policy.tsx) - model-picker: drop ', selected' from accessibilityLabel — the accessibilityState already announces selection (was announced twice) - session-list header: Plus (hitSlop 11) and Filter (hitSlop 12) expanded rects overlapped by 7px inside the 16px gap, so the later sibling stole taps; cap the facing slops at 8 - profile avatar: remove redundant hitSlop on an already 44dp box (also overlapped the filter button's slop) - screen-header: add accessibilityRole to the back button - button.tsx: drop the unused IconButton wrapper and touch size variant (no consumers; knip ignores ui/**, so it would ship as unchecked dead code) - child-session-section: use the exported ThemeColors type
jeanduplessis
approved these changes
Jul 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the remediation phases of
.plans/mobile-readability-touch-target-audit.md. The audit report itself is in.plans/mobile-ui-audit-findings.md(not committed, per repo policy on plans).Touch targets and accessibility
agents/chat-composer.tsx: send/stop now havehitSlopreaching 44dp, plusaccessibilityRole,accessibilityLabel, andaccessibilityState.profile-avatar-button.tsx: full 44dp box (h-11 w-11) withaccessibilityRoleand pressed feedback.screen-header.tsx: title dropdown gets 44dphitSlop+ role/label; the back button now hasaccessibilityRole="button".agents/session-list-screen.tsx(plus/filter): 44dp-reachinghitSlop,accessibilityRole, pressed feedback. The facing slops are capped at 8 so the two expanded targets don't overlap inside the 16px gap (overlapping sibling hit rects let the later sibling steal taps).Readability
ui/session-row.tsx,ui/configure-row.tsx: replacetext-[10.5px]/text-[11.5px]/text-[14.5px]arbitrary sizes with the nearest sanctionedtext-xs/text-smutilities.app/(app)/(tabs)/_layout.tsx: raise tab-label font size from 10px to 11px (with small letter-spacing).Tokenization (no more hardcoded brand-blue)
kiloclaw/model-picker.tsx: selected state moves fromborder-blue-500 bg-blue-500/5+#3b82f6toborder-primary bg-neutral-100 dark:bg-neutral-800+colors.primary(the established selected-card pattern fromexec-policy.tsx; an opaquebg-accent-softfill was tried first but is#E8F27Ain both themes, which made dark-mode card text and the primary-colored checkmark illegible). DecorativeBalanced/Frontiericon tints now use the existingagent-sky/agent-yukitile-bg tokens. The 'or select from 500+ models' link is enlarged to a 44dp target withaccessibilityRole='link'and a label.kiloclaw/settings/model-list.tsx: selectedCheckcolor →colors.primary.agents/child-session-section.tsx: running-tool icons / text / border move from#3b82f6/text-blue-500to theagent-skytoken set (theme-aware light + dark).Out of scope: chat gutters (already consistent at
px-4on bothmessage-bubble.tsxfiles), status-badge palettes (green / red / blue is a deliberate semantic set), the model-pickerperformanceDotColordots (same deliberate-decorative category), and the eyebrow / 10-11px metadata typography (intentional per the design contract).A
size='touch'Button variant and an a11y-enforcingIconButtonwrapper were originally added inui/button.tsxbut dropped in review: nothing consumed them, and knip ignoressrc/components/ui/**so they would have shipped as permanently unchecked dead code. They can return in the same PR as their first call site.Verification
Manual device verification is required but was not done by the agent (no simulator / device access in this worktree). Items to spot-check on iOS and Android, light + dark:
ChatComposer(agent chat): tap reliability and VoiceOver / TalkBack announcement of 'Send message' / 'Stop generating'.SessionHeader(ScreenHeaderwithonTitlePress): title now announces 'Open menu for <title>'. Back button announces as a button.primaryborder/check); the 'select from 500+ models' link target.SessionRow/ConfigureRowlong-title truncation (already hadnumberOfLines={1}, now attext-sm/text-xs).Automated checks:
pnpm format,pnpm typecheck(mobile + full repo),pnpm lint,pnpm test(360/360),pnpm check:unusedall clean.Visual Changes
Visual changes are limited to:
primary) border on a neutral fill (bg-neutral-100/dark:bg-neutral-800).SessionRowandConfigureRowrow titles / subtitles are 1-2px larger.hitSlopchanges are invisible; they expand the tap area without changing visual size.Screenshots were not captured by the agent; visual confirmation is part of the manual checklist above.
Reviewer Notes
Seven small commits; the last one applies review findings (dark-mode selected-card contrast, overlapping hitSlop rects, dropping the unused
IconButton/touchsurface,ThemeColorstype reuse, double 'selected' screen-reader announcement).Risk areas
getStatusBorderColorinchild-session-section.tsxnow takes the fullThemeColorsobject instead of justdestructiveColor. Tested only by typecheck and existing tests.hitSlopinsets on the session-list header buttons trade ~3dp of horizontal target for non-overlapping hit rects; vertical targets stay at 44dp.